perm filename COLMS.SAI[PUB,TES] blob sn#195733 filedate 1976-01-28 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00008 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	BEGOF("COLMS")
C00005 00003	PUBLIC INTEGER SIMPLE PROCEDURE COLSLEFT $"#
C00006 00004	PUBLIC SIMPLE PROCEDURE DAPART $"#
C00007 00005	PUBLIC SIMPLE PROCEDURE DMARGINS(BOOLEAN INWARD) $"#
C00010 00006	PUBLIC RECURSIVE BOOLEAN PROCEDURE MOVEGROUP(BOOLEAN OFFPAGE  INTEGER TOCOL, TOLINE, EXTRA) $"#
C00014 00007	PUBLIC RECURSIVE PROCEDURE TOCOLUMN(INTEGER COLNO) $"#
C00015 00008	FINISHED
C00016 ENDMK
C⊗;
BEGOF("COLMS")
COMMENT

This module handles columns, groups, and margins.

Each area instantiation record owns a two-dimensional array of
dimensions 2*columns by maxlines.  AA[1:COLS,*] contain the legs of
the COLS columns, and AA[COLS+1:COLS+COLS,*] contain the feet.  The
entry in AA is (if nonzero) an index into a MOLES array for the page
(MObility of LinES), in which bits are set to indicate that certain
lines must move with others in a group.  Little use is made of these
bits, for they were included for the unimplemented BOX FRAME feature.

There are also global variables GROUPM indicating that GROUP Mode is
activated, and GLINEM which is the MOLES index of the first line in
the current group (if it has been determined).

The current margin settings are in global variables LMARG and RMARG.
When area-switching occurs, the current margins are stuffed into the
area declaration record.  When the margins of the current area are
changed for the first time in a block, the old margin values are
stacked on ISTK in a MARGTYPE record., thus, at END of block, the
margins of all areas can be restored.  Further complication is caused
by NARROW-WIDEN nests, which behave like blocks but with their own
save-restore code (they should never have been implemented).

;

PROCEDURES
PUBLIC INTEGER SIMPLE PROCEDURE COLSLEFT ;$"#
IF COL = 0 THEN RETURN(COLS)
ELSE	BEGIN
	INTEGER COUNT, COLUMN ;	COUNT ← 0 ;
	FOR COLUMN ← (COL - 1) MOD COLS + 1 THRU COLS DO
		IF AA[COLUMN, 0] = 0 AND AA[COLUMN+COLS,0] = 0 THEN COUNT ← COUNT + 1 ;
	RETURN(COUNT-(IF LINESLEFT<0 THEN 1 ELSE 0)) ;
	END "COLSLEFT" ;
PUBLIC SIMPLE PROCEDURE DAPART ;$"#
IF ON THEN
BEGIN "DAPART"
DBREAK ; GLINEM ← 0 ; COMMENT ← TES 4/25/73 ; IF GROUPM=0 THEN RETURN ;
IF MOLESIDA THEN DPB(0,BELOWM(OLX)) ; GROUPM←0 ;
END "DAPART" ;
PUBLIC SIMPLE PROCEDURE DMARGINS(BOOLEAN INWARD) ;$"#
BEGIN
STRING S ; INTEGER L, R, W, ARIX, OLDIX, NEWIX ;
IF ON THEN DBREAK ;
ARIX ← IF AREAIXM THEN AREAIXM ELSE IXTEXT ; OLDIX ← MARGINS(ARIX) ; PASS ;
S ← IF THISTYPE > INTERNTYPE OR THISTYPE=-TERQ OR NEXTSCH(←) OR NEXTSCH(:) THEN NULL
    ELSE E(NULL, NULL) ;
IF FULSTR(S) OR ITSCH(<,>) THEN
	BEGIN "HAS PARAMS"
	L ← IF FULSTR(S) THEN CVD(S) ELSE 0 ;
	IF ITSCH(<,>) THEN BEGIN PASS ; R ← CVD(E("0",NULL)) END ELSE R ← 0 ;
	IF  NOT ON THEN RETURN ;
	MARGINS(ARIX) ← NEWIX ← PUSHI(MARGWDS, MARGTYPE) ;  W ← COLWID(ARIX) ;
	LMARG ← (IF OLDIX THEN LMARGX(OLDIX) ELSE 0) + INWARD*L MAX 0 MIN W-1 ;
	RMARG ← (IF OLDIX THEN RMARGX(OLDIX) ELSE W) - INWARD*R MIN W MAX LMARG+1 ;
	LMARGX(NEWIX) ← LMARG ; RMARGX(NEWIX) ← RMARG ;
	AREAX(NEWIX) ← ARIX ; OLD!MARGX(NEWIX) ← OLDIX ;
	END "HAS PARAMS"
ELSE IF  NOT ON THEN RETURN
ELSE IF OLDIX THEN
	BEGIN "UNNEST"
	AREAX(OLDIX) ← 0 ; comment, so ENDBLOCK won't use it ;
	MARGINS(ARIX) ← NEWIX ← OLD!MARGX(OLDIX) ;
	LMARG ← IF NEWIX THEN LMARGX(NEWIX) ELSE 0 ;
	RMARG ← IF NEWIX THEN RMARGX(NEWIX) ELSE COLWID(ARIX) ;
	IF OLDIX = IHED THEN IHED ← IHED - 1 - MARGWDS ;
	END "UNNEST"
ELSE WARN("=","Extra "&(IF INWARD>0 THEN "NARROW" ELSE "WIDEN")&" in Margin Nest") ;
END "DMARGINS" ;
PUBLIC RECURSIVE BOOLEAN PROCEDURE MOVEGROUP(BOOLEAN OFFPAGE ; INTEGER TOCOL, TOLINE, EXTRA) ;$"#
BEGIN "MOVEGROUP"
INTEGER SAVEAREA, LFOOT, PFOOT, FOOL, C, L, L1, L2, F, TC, TL, X ;
IF  NOT OFFPAGE THEN
	IF COL LEQ COLS<TOCOL OR TOCOL>2*COLS THEN BEGIN OFFPAGE←TRUE ; TOCOL ← IF COL>COLS THEN COLS+1 ELSE 1 END ;
IF OFFPAGE THEN
	BEGIN "OTHER PAGE"
	SAVEAREA ← IF AREAIXM THEN LDB(BIXNUM(AREAIXM)) ELSE SYMTEXT ;
	GRPTOP ← OLX ; GRPOLX ← GLINEM ; GLINEM ← 0 ; CLOSEAREA(AREAIXM, FALSE) ;
	MOLES[0]←OLX ; OPENFRAME ; IDASSIGN(NEWPGIDA←FRAMEIDA, NEWPAGE) ;
	IDASSIGN(MOLESF, NMOLES) ; IDASSIGN(SHORTF, NSHORT) ;
	SIDASSIGN(OWLSF, NOWLS) ; IDASSIGN(MLEADF, NMLEAD) ; TES 11/2/74 MILL LEADING;
	NOLX ← 0 ; TES 1/15/74 0 WAS OLX ; FIXFRAME(OLDPGIDA) ;
	NEXTCOUNTER(SYMPAGE,IXPAGE) ;
	NMOLES[0]←NSHORT[0]←NMLEAD[0]←NOLX;
	FIXFRAME(NEWPGIDA) ; IDASSIGN(OLDPGIDA←NEWPGIDA, OLDPAGE) ;
	F ← ARF ;
	WHILE F DO
		BEGIN
		IDASSIGN(AREAIDA←F, THISAREA) ; F ← ARA ;
		IF (X ← DEFA) THEN
			BEGIN OLD!ACTIVE(X)←NEW!ACTIVE(X); NEW!ACTIVE(X)←0 END ;
		END ;
	NEWPGIDA ← 0 ; OPENAREA(LDB(IXN(SAVEAREA))) ;
	IF FINDTRAN(SYMPAGE,4) THEN RESPOND(LLTHIS) ;
	IF TOCOL > COLS THEN BEGIN COL SWAP PAL ; LINE SWAP PINE END ;
	END "OTHER PAGE"
ELSE	BEGIN "SAME PAGE"
	GRPOLX ← GLINEM ; LFOOT ← 0 ; FOOL ← IF PAL>COL THEN PINE ELSE LINE ;
	PFOOT ← IF FOOL=0 THEN 0 ELSE IF LDB(FOOTM(AA[PAL MAX COL,FOOL]))=31 THEN 30 ELSE 0;
	FOR C ← COL, PAL DO
		BEGIN
		L1 ← 1 ; L2 ← IF C = COL THEN LINE ELSE PINE ;
		TC ← IF C=COL THEN TOCOL ELSE (TOCOL+COLS-1) MOD (2*COLS) + 1 ;
		TL ← IF C=COL THEN TOLINE-1 ELSE RH(AA[TC,0]) ;
		F ← IF C LEQ COLS THEN LFOOT ELSE PFOOT ;
		FOR L ← L1 THRU L2 DO IF (X ← AA[C,L]) GEQ GRPOLX THEN
			BEGIN
			AA[TC, TL ← TL + 1] ← X ; AA[C, L] ← 0 ;
			IF LDB(FOOTM(X)) THEN DPB(F←IF F=31 THEN 1 ELSE F+1, FOOTM(X)) ;
			END ;
		IF C= COL THEN BEGIN LINE ← TL ; COL ← TC END ELSE BEGIN PINE ← TL ; PAL ← TC END ;
		END ;
	GRPOLX ← 0 ;
	END "SAME PAGE" ;
DAPART ; RETURN(TRUE) ;
END "MOVEGROUP" ;
PUBLIC RECURSIVE PROCEDURE TOCOLUMN(INTEGER COLNO) ;$"#
IF ON THEN
BEGIN "TOCOLUMN"
ASSUREAREA ;
IF COLNO < COL OR (COLNO=COL AND LINE) OR TES 10/25/73; COLNO>COLS   THEN NEXTPAGE ;
IF 1 LEQ COLNO LEQ COLS THEN COL←COLNO ELSE
	BEGIN TES 10/25/73;
	WARN(NULL, "SKIP to nonexistent column "&CVS(COLNO));
	COLNO ← 1 ;
	END ;
LINE ← 0 ; IF COL>1 THEN OPENAREA(AREAIXM) ;
END "TOCOLUMN" ;
FINISHED

ENDOF("COLMS")